# 导入Python标准库中的csv模块，用于读写CSV文件
import csv

# 定义BMR计算函数，根据性别、年龄、体重和身高计算基础代谢率
def calculate_bmr(gender, age, weight, height):
    # 根据性别使用不同的哈里斯-本尼迪克特（Harris-Benedict）公式计算BMR
    if gender == '男':
        bmr = 66 + (13.75 * weight) + (5 * height) - (6.75 * age)
    elif gender == '女':
        bmr = 655 + (9.6 * weight) + (1.8 * height) - (4.7 * age)
    else:
        # 如果性别输入不是'男'或'女'，抛出ValueError异常
        raise ValueError("性别输入错误，请输入'男'或'女'")
    # 返回计算得到的BMR值
    return bmr

# 定义一个函数用于验证用户输入，确保输入数据的合理性
def validate_input(prompt, cast_type, condition=None):
    # 使用无限循环，直到获得有效输入
    while True:
        try:
            # 提示用户输入，并尝试将输入转换为指定类型cast_type
            user_input = cast_type(input(prompt))
            # 如果提供了条件函数condition，检查输入是否满足条件
            if condition and not condition(user_input):
                print("输入数据不符合要求，请重新输入。")
            else:
                # 如果输入有效，返回用户输入
                return user_input
        except ValueError:
            # 如果输入转换失败，打印错误信息并重新请求输入
            print("输入类型错误，请重新输入。")

# 主菜单模块，提供用户选择操作的界面
def menu():
    # 使用无限循环，直到用户选择退出
    while True:
        print("\n欢迎使用BMR计算器")
        print("1. 进入计算器")
        print("2. 退出程序")
        print("3. 生成CSV文件表头")
        # 请求用户输入选择
        choice = input("请选择一个操作：")
        if choice == '1':
            # 如果用户选择进入计算器，调用count函数
            count()
        elif choice == '2':
            # 如果用户选择退出，打印感谢信息并退出菜单循环
            print("感谢使用，再见！")
            break
        elif choice == '3':
            # 如果用户选择生成CSV文件表头，调用generate_csv_header函数
            generate_csv_header()
        else:
            # 如果用户输入无效，提示重新输入
            print("输入无效，请输入1、2或3。")

# 生成CSV文件表头模块，创建CSV文件并写入表头
def generate_csv_header():
    # 使用with语句安全地打开文件，写入表头并自动关闭文件
    with open('bmr_data.csv', 'w', newline='') as file:
        writer = csv.writer(file)
        writer.writerow(['性别', '年龄', '体重(kg)', '身高(m)', 'BMR(卡路里)', '建议'])
    # 打印信息告知用户表头已生成
    print("CSV文件表头已生成。")

# BMR计算模块，收集用户数据并计算BMR，并给出建议
def count():
    # 调用validate_input函数收集用户性别，确保输入为'男'或'女'
    gender = validate_input("请输入性别（男/女）：", str, lambda x: x in ['男', '女'])
    # 调用validate_input函数收集用户年龄，确保输入为正整数不超过100
    age = validate_input("请输入年龄：", int, lambda x: 0 < x <= 100)
    # 调用validate_input函数收集用户体重，确保输入为正数
    weight = validate_input("请输入体重（公斤）：", float, lambda x: x > 0)
    # 调用validate_input函数收集用户身高，确保输入为正数不超过2米
    height = validate_input("请输入身高（米）：", float, lambda x: 0 < x <= 2)

    # 尝试计算BMR并给出建议，如果发生ValueError异常，则捕获并打印错误信息
    try:
        bmr = calculate_bmr(gender, age, weight, height)
        # 根据BMR值给出不同范围的建议
        if bmr < 1200:
            advice = "你的BMR指数偏低，可能需要增加营养摄入或咨询医生。"
        elif 1200 <= bmr < 1500:
            advice = "你的BMR指数处于较低范围，注意饮食均衡。"
        elif 1500 <= bmr < 1800:
            advice = "你的BMR指数处于合理范围，继续保持健康的饮食和生活习惯。"
        elif 1800 <= bmr < 2200:
            advice = "你的BMR指数处于较高范围，注意饮食控制和适量运动。"
        else:
            advice = "你的BMR指数偏高，需要减少高热量食物的每日摄入，并通过适当强度的运动辅助代谢。"
        # 打印BMR结果和建议
        print(f"您的基础代谢率（BMR）是：{bmr}卡路里。")
        print(advice)
        # 调用save_to_csv函数保存数据和建议到CSV文件
        save_to_csv(gender, age, weight, height, bmr, advice)
    except ValueError as e:
        print(e)

# 将数据和建议写入CSV文件的函数
def save_to_csv(gender, age, weight, height, bmr, advice):
    # 使用with语句安全地打开文件，追加一行数据并自动关闭文件
    with open('bmr_data.csv', 'a', newline='') as file:
        writer = csv.writer(file)
        # 写入一行数据，包括性别、年龄、体重、身高、BMR和建议
        writer.writerow([gender, age, weight, height, bmr, advice])
    # 打印信息告知用户数据已保存
    print("数据和建议已保存到CSV文件。")

# 主函数，控制程序的执行流程
def main():
    # 程序开始时生成CSV文件表头
    generate_csv_header()
    # 进入主菜单
    menu()

# 程序入口点，当该脚本被Python解释器直接运行时执行main函数
if __name__ == "__main__":
    main()
